package com.thb.pay.system.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.google.common.collect.Lists;
import com.thb.pay.api.sys.vo.req.SysResourcePageReq;
import com.thb.pay.api.sys.vo.req.SysResourceReq;
import com.thb.pay.api.sys.vo.resp.SysResourceVo;
import com.thb.pay.core.utils.PageResult;
import com.thb.pay.db.service.impl.BaseServiceImpl;
import com.thb.pay.db.utils.PageResultUtils;
import com.thb.pay.db.utils.PageUtils;
import com.thb.pay.db.utils.QueryUtils;
import com.thb.pay.system.entity.SysResource;
import com.thb.pay.system.entity.SysRoleResource;
import com.thb.pay.system.entity.SysUserResource;
import com.thb.pay.system.mapper.SysResourceMapper;
import com.thb.pay.system.service.SysResourceService;
import com.thb.pay.system.service.SysRoleResourceService;
import com.thb.pay.system.service.SysUserResourceService;
import com.xiaoleilu.hutool.collection.CollUtil;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

import java.util.List;

/**
 * <p>
 * 系统-资源表 服务实现类
 * </p>
 *
 * @author lucky
 * @since 2019-07-21
 */
@Service
public class SysResourceServiceImpl extends BaseServiceImpl<SysResourceMapper, SysResource> implements SysResourceService {

    @Autowired
    private SysRoleResourceService sysRoleResourceService;

    @Autowired
    private SysUserResourceService sysUserResourceService;
    @Override
    public PageResult<SysResourceVo> findPage(SysResourcePageReq pageReq) {
        IPage<SysResource> currentPage = PageUtils.buildPage(pageReq);
        QueryWrapper wrapper = QueryUtils.buildQueryPage(pageReq);
        IPage<SysResource> pageResult = super.page(currentPage, wrapper);
        return PageResultUtils.build(pageResult, SysResourceVo.class);
    }

    @Override
    public List<SysResourceVo> findListByParentId(Long parentId) {
        Assert.notNull(parentId, "resource.parentId.not.null");
        List<SysResourceVo> targetList = Lists.newArrayList();
        LambdaQueryWrapper<SysResource> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SysResource::getParentId, parentId);
        List<SysResource> resList = super.selectList(wrapper);
        resList.forEach(sysResource -> {
            SysResourceVo targetResult = new SysResourceVo();
            BeanUtils.copyProperties(sysResource, targetResult);
            targetList.add(targetResult);
        });
        return targetList;
    }

    @Override
    public List<SysResourceVo> findListBySystemType(Integer systemType) {
        Assert.notNull(systemType, "resource.system.not.null");
        List<SysResourceVo> targetList = Lists.newArrayList();
        LambdaQueryWrapper<SysResource> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SysResource::getSystem, systemType);
        List<SysResource> resList = super.selectList(wrapper);
        resList.forEach(sysResource -> {
            SysResourceVo targetResult = new SysResourceVo();
            BeanUtils.copyProperties(sysResource, targetResult);
            targetList.add(targetResult);
        });
        return targetList;
    }

    @Override
    public SysResourceVo getByPermissionCode(String code) {
        Assert.notNull(code, "resource.permissionUrl.not.null");
        LambdaQueryWrapper<SysResource> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SysResource::getPermUrl, code);
        List<SysResource> resList = super.selectList(wrapper);
        if (CollUtil.isNotEmpty(resList)) {
            SysResourceVo targetResult = new SysResourceVo();
            BeanUtils.copyProperties(resList.get(0), targetResult);
            return targetResult;
        }
        return null;
    }

    @Override
    public void save(SysResourceReq resourceReq) {
        Assert.notNull(resourceReq, "resource.info.not.null");
        SysResource targetResult = new SysResource();
        BeanUtils.copyProperties(resourceReq, targetResult);
        super.save(targetResult);
    }

    @Override
    public void update(SysResourceReq resourceReq) {
        Assert.notNull(resourceReq, "resource.info.not.null");
        SysResource targetResult = new SysResource();
        BeanUtils.copyProperties(resourceReq, targetResult);
        super.updateById(targetResult);
    }

    @Override
    public List<SysResourceVo> findListByUserId(Long userId) {
        List<SysResourceVo> targetResultList = Lists.newArrayList();
        List<SysResource> resResultList = this.baseMapper.selectListByUserId(userId);
        copyResource(targetResultList, resResultList);
        return targetResultList;
    }

    @Override
    public List<SysResourceVo> findListByRoleIds(List<Long> roleIds) {
        List<SysResourceVo> targetResultList = Lists.newArrayList();
        List<SysResource> resResultList = this.baseMapper.selectListByRoleIds(roleIds);
        copyResource(targetResultList, resResultList);
        return targetResultList;
    }


    @Transactional
    @Override
    public void deleteBatchResourceIds(List<Long> resourceIds) {
        Assert.notEmpty(resourceIds, "resourceIds.not.empty");
        //删除 all 角色对应菜单的关系
        LambdaQueryWrapper<SysRoleResource> roleWrapper = new LambdaQueryWrapper<>();
        roleWrapper.in(SysRoleResource::getResourceId, resourceIds);
        sysRoleResourceService.delete(roleWrapper);


        LambdaQueryWrapper<SysUserResource> userWrapper = new LambdaQueryWrapper<>();
        userWrapper.in(SysUserResource::getResourceId, resourceIds);
        sysUserResourceService.delete(userWrapper);

        //删除菜单
        super.deleteBatchIds(resourceIds);
    }

    private void copyResource(List<SysResourceVo> targetResultList, List<SysResource> resResultList) {
        if (CollUtil.isNotEmpty(resResultList)) {
            resResultList.forEach(sysResource -> {
                SysResourceVo targetResult = new SysResourceVo();
                BeanUtils.copyProperties(sysResource, targetResult);
                targetResultList.add(targetResult);
            });
        }
    }
}
